import 'dart:async';
import 'dart:convert';

Future<void> sayHello() async {
  var val = await Future.value(20);
}

Stream<num> getRange3(num end) async* {
  for (var i = 0; i < end; i++) {
    yield i;
  }
}

Stream<num> getRange2(num end) {
  return Stream.fromIterable(Iterable.generate(end, (v) => v));
}

Stream<num> getRange1(num end) {
  var scl = StreamController();
  for (var i = 0; i < end; i++) {
    scl.sink.add(i);
  }
  return scl.stream;
}

main(List<String> args) {
  var ct1 = Completer();
  var ct2 = Completer.sync();

  ct1.future.then((value) => print(value));
  ct2.future.then(print);

  ct1.complete("same");
//  ct1.completeError("error");

  Future future1 = Future.value("hello");
  Future.value(10)
      .then((value) => print(value))
      .catchError((e) => print(e))
      .whenComplete(() => {print("finish")});

  Future.value(20)
      .then((value) => 30)
      .then((value) => Future.value(40))
      .then((value) => print(value));

  Future.delayed(Duration(milliseconds: 1000));
  Future.error("error");
  Future.sync(() => 20);

  Future.wait([future1]);

  Future.microtask(() => {2}).then((value) => print(value));

  Future.forEach([9, 8, 6], (element) => {print(element), Future.value(10)});

  Future.any([Future.value(88), Future.value(99)])
      .then((value) => print(value));

  scheduleMicrotask(() {
    Future.value(1).then((value) => print(value));
  });

  scheduleMicrotask(() {
    print("dfff");
  });

  var s1 = StreamController.broadcast();
  s1.stream.listen((event) {
    print(event);
  });
  s1.stream.listen((event) {
    print(event);
  });
  s1.sink.add(1);

  var s2 = Stream.fromFutures([Future.value(2)]);
  var s3 = Stream.periodic(Duration(seconds: 1));
  var s5 = Stream<String>.eventTransformed(s3, (sink) => LogSink(sink));
  var s6 = Stream.fromFuture(Future.value(2));
  var s7 = s3.asyncExpand((event) => Stream.fromFuture(Future.value(20)));
  var s8 = Stream.fromFuture(Future.value(2)).expand((i) => [i, i]);
  s7.toList().then((value) => print(value));
  s8.toList().then((value) => print(value));
  LineSplitter;

  var ctl2 = StreamController<int>();
  var stream1 = Stream.fromIterable([1, 2, 3]);
//  stream1.pipe(ctl2.sink);
  ctl2.addStream(stream1);

  stream1.timeout(Duration(seconds: 2), onTimeout: (sink) {
    print("time out");
  });
  stream1.asBroadcastStream();
//  stream1.drain();
  Stream.fromIterable([1, 2, 2, 3])
      .distinct()
      .toList()
      .then((value) => print(value));
  var transformer = StreamTransformer.fromBind((s) => s);
  StreamTransformer.fromHandlers(
    handleData: (v, sink) {
      sink.add(v + 2);
    },
    handleDone: (sink) {},
    handleError: (obj, errStack, sink) {},
  );
//  stream1.transform(transformer);

  Stream.fromIterable([1, 2, 3])
      .map((event) => event + 1)
      .toList()
      .then((value) => print(value));
}

class LogSink implements EventSink<String> {
  final EventSink<String> _outputSink;

  LogSink(this._outputSink);

  void add(String data) {
    print(">>>>>> the data is $data");
    _outputSink.add(data);
  }

  void addError(e, [st]) {
    _outputSink.addError(e, st);
  }

  void close() {
    _outputSink.close();
  }
}
